package controller;

import gui.OptionPanel;
import gui.StatusBar;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.vecmath.Point3d;

import buildtools.Connector;

import com.sun.j3d.utils.picking.PickResult;

import component.AbstractComponent;
import component.Ball;
import component.Status;
import component.Structure;
import component.Tube;
import controller.transform.Gui;
import controller.transform.InitMode;
import controller.transform.ModeListener;
import controller.transform.Scene;
import controller.transform.TransformMode;
import controller.transform.TransformPanel;

public class TransformController extends AbstractController implements ModeListener {
	
	private final Structure structure;
	private final OptionPanel optionPanel;
	private final StatusBar statusBar;
	private final CameraController camera;
	
	private TransformMode transformMode = null;
	
	private final Scene scene;
	private final Gui gui;
	
	private final TransformPanel transformPanel;
	private final TransformHelper helper;
	
	private final Connector connector;
	
	public TransformController(Canvas3D canvas, BranchGroup pickableBranch,
			Structure structure,
			OptionPanel optionPanel,
			StatusBar statusBar,
			CameraController camera) {
		super(canvas, pickableBranch);
		this.structure = structure;
		this.optionPanel = optionPanel;
		this.statusBar = statusBar;
		this.camera = camera;
		helper = new TransformHelper();
		gui = helper;
		scene = helper;
		transformPanel = new TransformPanel(this);
		connector = new Connector(structure);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		transformMode = transformMode.mousePressed(e);
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		transformMode = transformMode.mouseReleased(e);
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		transformMode = transformMode.mouseDragged(e);
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		transformMode = transformMode.mouseMoved(e);
	}

	@Override
	public void mouseWheelMoved(MouseWheelEvent e) {
	}

	@Override
	public void keyPressed(KeyEvent e) {
		transformMode = transformMode.keyPressed(e);
	}

	@Override
	public void keyReleased(KeyEvent e) {
		transformMode = transformMode.keyReleased(e);
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void activate() {
		this.transformMode = new InitMode(gui, scene);
		this.optionPanel.setPanel(transformPanel);
	}

	@Override
	public void deactivate() {
		this.scene.resetState();
		this.gui.unlockCamera();
		this.statusBar.clearStatus();
		if (transformMode != null) {
			transformMode.deselected();
		}
		this.optionPanel.clearPanel();
	}
	
	private class TransformHelper implements Gui, Scene {

		private Ball pivot = null;
		private Tube axis = null;
		
		private int mode = TransformPanel.ROTATION_MODE;
		
		@Override
		public AbstractComponent pickClosest(MouseEvent e) {
			PickResult result = TransformController.this.pickClosest(e);
			return TransformController.this.getComponent(result);
		}

		@Override
		public void setMode(int mode) {
			this.mode = mode;
		}

		@Override
		public int getMode() {
			return this.mode;
		}

		@Override
		public void setPivot(Ball pivot) {
			this.pivot = pivot;
		}

		@Override
		public Ball getPivot() {
			return this.pivot;
		}

		@Override
		public void setAxis(Tube axis) {
			this.axis = axis;
		}
		
		@Override
		public Tube getAxis() {
			return this.axis;
		}

		@Override
		public Point3d getCameraPosition() {
			return camera.getCameraPos();
		}

		@Override
		public void lockCamera() {
			camera.lockCamera();
		}

		@Override
		public void unlockCamera() {
			camera.unlockCamera();
		}

		@Override
		public void setStatusText(String text) {
			statusBar.setStatus(text);
		}

		@Override
		public void resetState() {
			if (axis != null)
				axis.setStatus(Status.NORMAL);
			if (pivot != null) {
				pivot.setStatus(Status.NORMAL);
			}
			
			axis = null;
			pivot = null;
		}

		@Override
		public Structure getStructure() {
			return structure;
		}

		@Override
		public Point3d getCameraFocus() {
			return camera.getCameraFocus();
		}

		@Override
		public void connectPossible() {
			connector.connectAllPossible();
			
		}
		
	}

	@Override
	public void newMode(int mode) {
		this.helper.setMode(mode);
		this.transformMode.deselected();
		this.transformMode = new InitMode(helper, helper);
	}

}
